package game;

import opengl.program.GLProgramManager;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;

import sys.SysParam;
import world.Camera;
import world.WorldManager;

public class Game3DService implements GameService {
	public static GameService get() {
		if (instance == null) {
			instance = new Game3DService();
			instance.glProgramManager = GLProgramManager.get();
			instance.worldManager = WorldManager.get();
		}
		return instance;
	}

	// ----------------------------------------------------------------private
	private static Game3DService instance;
	public GLProgramManager glProgramManager = GLProgramManager.get();
	public WorldManager worldManager = WorldManager.get();
	

	public void load(){
		worldManager.loadWorld();
	}
	

	public void resized(){
		glProgramManager.resized(SysParam.SCREEN_WIDTH, SysParam.SCREEN_WIDTH);
	}

	
	public void init() throws Exception{
		glProgramManager.init();
	}
		
	public void render() {
		Camera camera = worldManager.getCamera();
		glProgramManager.getBlockProgram().begin();
		{
			GL20.glUniformMatrix4(glProgramManager.getBlockProgram().getCameraMatrixUniform(), false, camera.calcLookAtMatrix().toBuffer());
			GL20.glUniformMatrix4(glProgramManager.getBlockProgram().getModelMatrixUniform(), false, worldManager.getWorldMatix().toBuffer());
			worldManager.renderWorld();
		}
		glProgramManager.getBlockProgram().end();

		glProgramManager.getBaseProgram().begin();
		{
			GL11.glDisable(GL11.GL_DEPTH_TEST);
			GL11.glDepthMask(false);
			worldManager.renderCrosshair();
			GL11.glEnable(GL11.GL_DEPTH_TEST);
			GL11.glDepthMask(true);
		}
		glProgramManager.getBaseProgram().end();

		glProgramManager.getLineProgram().begin();
		{
			GL20.glUniformMatrix4(glProgramManager.getLineProgram().getCameraMatrixUniform(), false, camera.calcLookAtMatrix().toBuffer());
			GL11.glLineWidth(2);
			worldManager.renderCoordinator();
		}
		glProgramManager.getLineProgram().end();
	}
}
